Hmac Object
Hmac வகுப்பு Node.js இன் crypto தொகுதியின் ஒரு பகுதியாகும். இது கிரிப்டோகிராஃபிக் HMAC (Hash-based Message Authentication Code) டைஜெஸ்ட்களை உருவாக்க ஒரு வழியை வழங்குகிறது. HMAC நிகழ்வுகள் crypto.createHmac() முறையைப் பயன்படுத்தி உருவாக்கப்படுகின்றன.
HMAC ஒரு கிரிப்டோகிராஃபிக் ஹாஷ் செயல்பாட்டை ஒரு ரகசிய விசையுடன் இணைக்கிறது, இது செய்தி அங்கீகார குறியீட்டை உருவாக்குகிறது, இது தரவு ஒருமைப்பாடு மற்றும் அங்கீகாரம் இரண்டையும் வழங்குகிறது.
Import Crypto Module
// Import the crypto module
const crypto = require('crypto');
// Create an Hmac object
const hmac = crypto.createHmac('sha256', 'your-secret-key');
Hmac Methods
| முறை | விளக்கம் |
|---|---|
| hmac.update(data[, inputEncoding]) | கொடுக்கப்பட்ட தரவுடன் Hmac உள்ளடக்கத்தைப் புதுப்பிக்கிறது. inputEncoding வழங்கப்பட்டால், தரவு குறிப்பிட்ட குறியீட்டைப் பயன்படுத்தி ஒரு சரமாகும்; இல்லையெனில், தரவு ஒரு Buffer, TypedArray, அல்லது DataView ஆகும். இந்த முறை புதிய தரவுடன் பல முறை அழைக்கப்படலாம். |
| hmac.digest([encoding]) | hmac.update() ஐப் பயன்படுத்தி அனுப்பப்பட்ட அனைத்து தரவின் HMAC டைஜெஸ்டைக் கணக்கிடுகிறது. encoding வழங்கப்பட்டால், ஒரு சரம் திரும்பும்; இல்லையெனில், ஒரு Buffer திரும்பும். இந்த முறை அழைக்கப்பட்ட பிறகு, Hmac பொருள் இனி பயன்படுத்தப்பட முடியாது. |
Basic Hmac Example
பின்வரும் எடுத்துக்காட்டு ஒரு சரத்தின் HMAC டைஜெஸ்டை எவ்வாறு உருவாக்குவது என்பதை விளக்குகிறது:
const crypto = require('crypto');
// Data to authenticate
const data = 'Hello, World!';
// Secret key
const secretKey = 'my-secret-key';
// Create an Hmac object
const hmac = crypto.createHmac('sha256', secretKey);
// Update the hmac with data
hmac.update(data);
// Get the digest in hex format
const digest = hmac.digest('hex');
console.log('Data:', data);
console.log('Secret Key:', secretKey);
console.log('HMAC-SHA256:', digest);
Comparing Different HMAC Algorithms
இந்த எடுத்துக்காட்டு HMAC உடன் வெவ்வேறு ஹாஷ் அல்காரிதம்களை ஒப்பிடுகிறது:
const crypto = require('crypto');
// Data to authenticate
const data = 'Node.js Crypto HMAC Example';
// Secret key
const secretKey = 'my-secret-key';
// Function to create HMAC with different algorithms
function createHmacWithAlgorithm(algorithm, data, key) {
const hmac = crypto.createHmac(algorithm, key);
hmac.update(data);
return hmac.digest('hex');
}
// Test various HMAC algorithms
const algorithms = ['md5', 'sha1', 'sha256', 'sha512', 'sha3-256', 'sha3-512'];
console.log(`Data: "${data}"`);
console.log(`Secret Key: "${secretKey}"`);
console.log('------------------------------------');
algorithms.forEach(algorithm => {
try {
const digest = createHmacWithAlgorithm(algorithm, data, secretKey);
console.log(`HMAC-${algorithm}: ${digest}`);
console.log(`Length: ${digest.length / 2} bytes (${digest.length * 4} bits)`);
console.log('------------------------------------');
} catch (error) {
console.log(`HMAC-${algorithm}: Not supported - ${error.message}`);
console.log('------------------------------------');
}
});
HMAC with Multiple Updates
டைஜெஸ்டைக் கணக்கிடுவதற்கு முன் பல தரவுத் துண்டுகளுடன் ஒரு HMAC ஐப் புதுப்பிக்கலாம்:
const crypto = require('crypto');
// Secret key
const secretKey = 'my-secret-key';
// Create an Hmac object
const hmac = crypto.createHmac('sha256', secretKey);
// Update the hmac with multiple pieces of data
hmac.update('First part of the data.');
hmac.update(' Second part of the data.');
hmac.update(' Third part of the data.');
// Calculate the final digest
const digest = hmac.digest('hex');
console.log('Combined data: First part of the data. Second part of the data. Third part of the data.');
console.log('Secret Key:', secretKey);
console.log('HMAC-SHA256:', digest);
// You can achieve the same result with a single update
const singleHmac = crypto.createHmac('sha256', secretKey);
singleHmac.update('First part of the data. Second part of the data. Third part of the data.');
const singleDigest = singleHmac.digest('hex');
console.log('Single update HMAC matches multiple updates?', singleDigest === digest);
HMAC with Different Encodings
நீங்கள் வெவ்வேறு குறியீடுகளில் HMAC டைஜெஸ்டைப் பெறலாம்:
const crypto = require('crypto');
// Data to authenticate
const data = 'Hello, Node.js!';
// Secret key
const secretKey = 'my-secret-key';
// Function to create HMAC and get digest in different encodings
function createHmacWithEncoding(algorithm, data, key, encoding) {
const hmac = crypto.createHmac(algorithm, key);
hmac.update(data);
return hmac.digest(encoding);
}
// Create HMAC with SHA-256 and display in different encodings
console.log(`Data: "${data}"`);
console.log(`Secret Key: "${secretKey}"`);
console.log(`HMAC-SHA256 (hex): ${createHmacWithEncoding('sha256', data, secretKey, 'hex')}`);
console.log(`HMAC-SHA256 (base64): ${createHmacWithEncoding('sha256', data, secretKey, 'base64')}`);
console.log(`HMAC-SHA256 (base64url): ${createHmacWithEncoding('sha256', data, secretKey, 'base64url')}`);
console.log(`HMAC-SHA256 (binary): ${createHmacWithEncoding('sha256', data, secretKey, 'binary')}`);
// Get the digest as a Buffer (no encoding)
const hmac = crypto.createHmac('sha256', secretKey);
hmac.update(data);
const buffer = hmac.digest();
console.log('HMAC-SHA256 (Buffer):', buffer);
console.log('Buffer length:', buffer.length, 'bytes');
File Authentication with HMAC
நீங்கள் ஒரு கோப்பின் உள்ளடக்கங்களின் HMAC டைஜெஸ்டை உருவாக்கலாம்:
const crypto = require('crypto');
const fs = require('fs');
// Function to create HMAC for a file using streams
function createHmacForFile(filePath, algorithm, key) {
return new Promise((resolve, reject) => {
// Create Hmac object
const hmac = crypto.createHmac(algorithm, key);
// Create read stream
const stream = fs.createReadStream(filePath);
// Handle stream events
stream.on('data', (data) => {
hmac.update(data);
});
stream.on('end', () => {
const digest = hmac.digest('hex');
resolve(digest);
});
stream.on('error', (error) => {
reject(error);
});
});
}
// Secret key
const secretKey = 'file-authentication-key';
// Example usage (adjust file path as needed)
const filePath = 'example.txt';
// Create a test file if it doesn't exist
if (!fs.existsSync(filePath)) {
fs.writeFileSync(filePath, 'This is a test file for HMAC authentication.\n'.repeat(100));
console.log(`Created test file: ${filePath}`);
}
// Create HMAC for the file with different algorithms
Promise.all([
createHmacForFile(filePath, 'md5', secretKey),
createHmacForFile(filePath, 'sha1', secretKey),
createHmacForFile(filePath, 'sha256', secretKey)
])
.then(([md5Digest, sha1Digest, sha256Digest]) => {
console.log(`File: ${filePath}`);
console.log(`Secret Key: ${secretKey}`);
console.log(`HMAC-MD5: ${md5Digest}`);
console.log(`HMAC-SHA1: ${sha1Digest}`);
console.log(`HMAC-SHA256: ${sha256Digest}`);
// Store the HMAC for later verification
fs.writeFileSync(`${filePath}.hmac`, sha256Digest);
console.log(`HMAC stored in: ${filePath}.hmac`);
})
.catch(error => {
console.error('Error creating HMAC for file:', error.message);
});
Verifying File Integrity with HMAC
இந்த எடுத்துக்காட்டு முன்பு உருவாக்கப்பட்ட HMAC ஐப் பயன்படுத்தி ஒரு கோப்பின் ஒருமைப்பாட்டை எவ்வாறு சரிபார்க்க வேண்டும் என்பதை விளக்குகிறது:
const crypto = require('crypto');
const fs = require('fs');
// Function to create HMAC for a file
function createHmacForFile(filePath, algorithm, key) {
return new Promise((resolve, reject) => {
const hmac = crypto.createHmac(algorithm, key);
const stream = fs.createReadStream(filePath);
stream.on('data', (data) => {
hmac.update(data);
});
stream.on('end', () => {
const digest = hmac.digest('hex');
resolve(digest);
});
stream.on('error', (error) => {
reject(error);
});
});
}
// Function to verify file integrity
async function verifyFileIntegrity(filePath, storedHmacPath, algorithm, key) {
try {
// Read the stored HMAC
const storedHmac = fs.readFileSync(storedHmacPath, 'utf8').trim();
// Calculate the current HMAC
const currentHmac = await createHmacForFile(filePath, algorithm, key);
// Compare the HMACs
const isValid = currentHmac === storedHmac;
return {
isValid,
storedHmac,
currentHmac
};
} catch (error) {
throw new Error(`Verification failed: ${error.message}`);
}
}
// Secret key (must be the same as used to create the original HMAC)
const secretKey = 'file-authentication-key';
// Example usage
const filePath = 'example.txt';
const hmacPath = `${filePath}.hmac`;
// Verify the file integrity
verifyFileIntegrity(filePath, hmacPath, 'sha256', secretKey)
.then(result => {
console.log(`File: ${filePath}`);
console.log(`HMAC file: ${hmacPath}`);
console.log(`Integrity verified: ${result.isValid}`);
if (!result.isValid) {
console.log('Stored HMAC:', result.storedHmac);
console.log('Current HMAC:', result.currentHmac);
console.log('The file has been modified!');
} else {
console.log('The file is intact and has not been tampered with.');
}
})
.catch(error => {
console.error('Error:', error.message);
});
Using Different Types of Keys
HMAC வெவ்வேறு வகையான விசைகளுடன் வேலை செய்யலாம்:
const crypto = require('crypto');
// Data to authenticate
const data = 'Data to authenticate with HMAC';
// Function to create HMAC with different key types
function createHmacWithKey(algorithm, data, key, keyType) {
const hmac = crypto.createHmac(algorithm, key);
hmac.update(data);
return {
keyType,
hmac: hmac.digest('hex')
};
}
console.log(`Data: "${data}"`);
console.log('------------------------------------');
// 1. String key
const stringKey = 'my-secret-key';
console.log(createHmacWithKey('sha256', data, stringKey, 'String key'));
// 2. Buffer key
const bufferKey = Buffer.from('buffer-secret-key');
console.log(createHmacWithKey('sha256', data, bufferKey, 'Buffer key'));
// 3. TypedArray key
const uint8ArrayKey = new Uint8Array([72, 101, 108, 108, 111]); // "Hello" in ASCII
console.log(createHmacWithKey('sha256', data, uint8ArrayKey, 'Uint8Array key'));
// 4. DataView key
const arrayBuffer = new ArrayBuffer(5);
const dataView = new DataView(arrayBuffer);
dataView.setUint8(0, 72); // H
dataView.setUint8(1, 101); // e
dataView.setUint8(2, 108); // l
dataView.setUint8(3, 108); // l
dataView.setUint8(4, 111); // o
console.log(createHmacWithKey('sha256', data, dataView, 'DataView key'));
// 5. KeyObject (recommended for sensitive keys)
const keyObject = crypto.createSecretKey(Buffer.from('key-object-secret'));
console.log(createHmacWithKey('sha256', data, keyObject, 'KeyObject');
HMAC for API Authentication
HMAC பொதுவாக API அங்கீகாரத்திற்குப் பயன்படுத்தப்படுகிறது, அங்கு சேவையகம் மற்றும் கிளையன்ட் ஒரு ரகசிய விசையைப் பகிர்ந்து கொள்கின்றன:
const crypto = require('crypto');
// Simulated API request
function createApiRequest(apiKey, secretKey, method, path, queryParams, body, timestamp) {
// Create the string to sign
const stringToSign = [
method.toUpperCase(),
path,
new URLSearchParams(queryParams).toString(),
typeof body === 'string' ? body : JSON.stringify(body || {}),
timestamp
].join('\n');
// Create HMAC signature
const hmac = crypto.createHmac('sha256', secretKey);
hmac.update(stringToSign);
const signature = hmac.digest('hex');
// Return the request with authentication headers
return {
url: `https://api.example.com${path}?${new URLSearchParams(queryParams)}`,
method,
headers: {
'Content-Type': 'application/json',
'X-Api-Key': apiKey,
'X-Timestamp': timestamp,
'X-Signature': signature
},
body: body || {},
// For debugging/verification
stringToSign
};
}
// Simulate API server verification
function verifyApiRequest(apiKey, secretKey, method, path, queryParams, body, timestamp, signature) {
// Recreate the string that was signed
const stringToSign = [
method.toUpperCase(),
path,
new URLSearchParams(queryParams).toString(),
typeof body === 'string' ? body : JSON.stringify(body || {}),
timestamp
].join('\n');
// Verify HMAC signature
const hmac = crypto.createHmac('sha256', secretKey);
hmac.update(stringToSign);
const expectedSignature = hmac.digest('hex');
return {
isValid: crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
),
expectedSignature
};
}
// API credentials
const apiKey = 'user123';
const secretKey = 'very-secret-api-key';
// Create a request
const timestamp = new Date().toISOString();
const request = createApiRequest(
apiKey,
secretKey,
'POST',
'/api/v1/users',
{ filter: 'active' },
{ name: 'John Doe', email: 'john@example.com' },
timestamp
);
console.log('API Request:');
console.log(`URL: ${request.url}`);
console.log(`Method: ${request.method}`);
console.log('Headers:', request.headers);
console.log('Body:', request.body);
console.log('\nString that was signed:');
console.log(request.stringToSign);
// Server verifies the request
const verification = verifyApiRequest(
apiKey,
secretKey,
'POST',
'/api/v1/users',
{ filter: 'active' },
{ name: 'John Doe', email: 'john@example.com' },
timestamp,
request.headers['X-Signature']
);
console.log('\nVerification result:');
console.log(`Is signature valid? ${verification.isValid}`);
// Try with tampered data
const tamperedVerification = verifyApiRequest(
apiKey,
secretKey,
'POST',
'/api/v1/users',
{ filter: 'active' },
{ name: 'Jane Doe', email: 'jane@example.com' }, // Changed body
timestamp,
request.headers['X-Signature']
);
console.log('\nTampered verification result:');
console.log(`Is signature valid? ${tamperedVerification.isValid}`);
HMAC vs Plain Hash
இந்த எடுத்துக்காட்டு ஒரு வெற்று ஹாஷ் மற்றும் ஒரு HMAC இடையே உள்ள வித்தியாசத்தை விளக்குகிறது:
const crypto = require('crypto');
// Data and keys
const data = 'Message to authenticate';
const key1 = 'secret-key-1';
const key2 = 'secret-key-2';
// Plain SHA-256 hash (no key)
function createHash(data) {
const hash = crypto.createHash('sha256');
hash.update(data);
return hash.digest('hex');
}
// HMAC-SHA-256 (with key)
function createHmac(data, key) {
const hmac = crypto.createHmac('sha256', key);
hmac.update(data);
return hmac.digest('hex');
}
// Compare results
console.log(`Data: "${data}"`);
console.log('\nPlain SHA-256 (no key):');
console.log(createHash(data));
console.log('\nHMAC-SHA-256 with key1:');
console.log(createHmac(data, key1));
console.log('\nHMAC-SHA-256 with key2:');
console.log(createHmac(data, key2));
// Demonstrate hash extension attack vulnerability
// This is a simplified illustration - actual extension attacks are more complex
console.log('\nHash Extension Attack Vulnerability:');
const originalData = 'original-message';
const originalHash = createHash(originalData);
console.log(`Original data: "${originalData}"`);
console.log(`Original SHA-256: ${originalHash}`);
// Attacker doesn't know the original data, but knows its hash
// and wants to append malicious data
const appendedData = 'malicious-appendage';
const combinedData = `${originalData}${appendedData}`;
const combinedHash = createHash(combinedData);
console.log(`Appended data: "${appendedData}"`);
console.log(`Combined data: "${combinedData}"`);
console.log(`Combined SHA-256: ${combinedHash}`);
console.log('With plain hash, an attacker who knows the hash of original data can compute valid hash for combined data without knowing the original data');
// HMAC is not vulnerable to extension attacks
console.log('\nHMAC Protection:');
const originalHmac = createHmac(originalData, key1);
const combinedHmac = createHmac(combinedData, key1);
console.log(`Original HMAC: ${originalHmac}`);
console.log(`Combined HMAC: ${combinedHmac}`);
console.log('With HMAC, an attacker cannot compute a valid HMAC for combined data without knowing the secret key');
Security Best Practices
HMAC ஐப் பயன்படுத்தும் போது, இந்த பாதுகாப்பு சிறந்த நடைமுறைகளைக் கவனியுங்கள்:
Common Use Cases for HMAC
API Authentication
அனுப்புநரின் அடையாளம் மற்றும் தரவு ஒருமைப்பாட்டைச் சரிபார்க்க API கோரிக்கைகளில் கையொப்பமிடுதல்
Message Authentication
பரிமாற்றத்தின் போது செய்திகள் திருத்தப்படவில்லை என்பதை உறுதிப்படுத்துதல்
Cookie/Token Verification
வலை பயன்பாடுகளில் கையொப்பமிடப்பட்ட குக்கீகள் அல்லது டோக்கன்களை உருவாக்குதல் மற்றும் சரிபார்த்தல்
File Integrity Verification
கோப்புகள் மாற்றப்படவில்லை அல்லது சிதைக்கப்படவில்லை என்பதைச் சரிபார்த்தல்
Password Storage
bcrypt போன்ற சிறப்பு அல்காரிதம்கள் விரும்பப்படினும், HMAC ஒரு கடவுச்சொல் ஹாஷிங் திட்டத்தின் ஒரு பகுதியாக பயன்படுத்தப்படலாம்
Key Derivation
HKDF போன்ற விசை பெறுதல் செயல்பாடுகளில் ஒரு கூறாக